package com.gshocklab.bulkposter.view;

import java.io.InputStream;
import java.net.URL;
import java.util.List;

import oauth.signpost.OAuth;
import android.app.ListActivity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.DialogInterface.OnClickListener;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.Toast;

import com.gshocklab.bulkposter.R;
import com.gshocklab.bulkposter.connection.TwitterConnectionHelper;
import com.gshocklab.bulkposter.data.AccountType;
import com.gshocklab.bulkposter.data.DatabaseAdapter;
import com.gshocklab.bulkposter.data.dto.SocialAccount;
import com.gshocklab.bulkposter.view.adapter.AccountsListAdapter;
import com.gshocklab.bulkposter.view.helper.ApplicationDialogs;
import com.gshocklab.bulkposter.view.helper.ApplicationDialogs.IConfirmDialogListener;
import com.gshocklab.bulkposter.view.helper.ApplicationDialogs.ISetupAccountDialogListener;

/**
 * Activity for Accounts screen
 * @author vitaly gashock
 */

public class AccountsActivity extends ListActivity {
	private List<SocialAccount> mRegisteredAccounts;
	private DatabaseAdapter mDbAdapter;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		setContentView(R.layout.accounts_list);
		registerForContextMenu(getListView());
		
		mDbAdapter = new DatabaseAdapter(this);
		
		refreshAccountsList();
	}

	private void refreshAccountsList() {
		mRegisteredAccounts = mDbAdapter.getRegisteredAccounts();
		setListAdapter(new AccountsListAdapter(this, mRegisteredAccounts));
		
		if (mRegisteredAccounts.isEmpty()) {
			ApplicationDialogs.showToast(this, "There are no registered accounts");
		}
	}
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.accounts_menu, menu);
		return true;
	}
	
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		final SocialAccount selectedAccount = (SocialAccount) getListView().getSelectedItem();
		
		switch (item.getItemId()) {
			case R.id.new_account:
				displaySelectAccountTypeDialog();
				return true;
			case R.id.delete_account:
				performAccountRemoving(selectedAccount);
				return true;
			case R.id.account_details :
				showAccountDetails(selectedAccount);
				return true;
			default:
				return super.onOptionsItemSelected(item);
		}
	}
	
	@Override
	public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo menuInfo) {
		menu.setHeaderTitle("Item actions");

		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.accounts_list_context_menu, menu);
	}
	
	@Override
	public boolean onContextItemSelected(MenuItem item) {
		AdapterView.AdapterContextMenuInfo info;
		SocialAccount selectedAccount;
		
        try {
             info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
             selectedAccount = (SocialAccount) getListAdapter().getItem(info.position);
        } catch (ClassCastException e) {
            Log.e("BulkPoster:AccountsActivity", "bad menuInfo", e);
            return false;
        } 
		
        switch (item.getItemId()) {
        	case R.id.details_account_item :
        		showAccountDetails(selectedAccount);
        		return true;
        	case R.id.delete_account_item :
        		performAccountRemoving(selectedAccount);
        		return true;
        }
        
		return true;
	}
	
	private void performAccountRemoving(final SocialAccount account) {
		ApplicationDialogs.showConfirmDialog(this, "Remove account", 
			"Proceed account removing?", 
			new IConfirmDialogListener() {
				@Override
				public void onYes() {
					if (mDbAdapter.deleteSocialAccount(account)) refreshAccountsList();
				}

				@Override
				public void onNo() { }
			});
	}
	
	private void displaySelectAccountTypeDialog() {
		ApplicationDialogs.showSelectAccountTypeDialog(this, "Select network", new OnClickListener() {
			@Override
			public void onClick(DialogInterface dialogInterface, int selectedItemId) {
				setupAccount(selectedItemId);
			}
		});
	}
	
	private void setupAccount(int accountId) {
		if (accountId == AccountType.TWITTER_ACCOUNT) {
			requestTwitterAccountRegistration();
		} else {
			ApplicationDialogs.showSetupAccountDialog(this, accountId, new ISetupAccountDialogListener() {
				@Override
				public void dataGathered(SocialAccount socialAccount) {
					long rowId = mDbAdapter.insertAccount(socialAccount);
					if (rowId > 0) refreshAccountsList();
				}
			});
		}
	}
	
	@Override
	protected void onListItemClick(ListView l, View v, int position, long id) {
		final SocialAccount selectedAccount = (SocialAccount) l.getItemAtPosition(position);
		showAccountDetails(selectedAccount);
	}
	
	private void showAccountDetails(final SocialAccount registeredAccount) {
		Drawable avatarDrawable = null;
		
		if (registeredAccount.avatarUrl != null && registeredAccount.avatarUrl.length() != 0) {
			// fetch avatar image from network by URL
			Context ctx = getApplicationContext();
			try {
				final URL avatarUrl = new URL(registeredAccount.avatarUrl);
				final InputStream is = (InputStream) avatarUrl.getContent();
				avatarDrawable = Drawable.createFromStream(is, "src");
			} catch (Exception e) {
				Log.e("ACCOUNTS_ACTIVITY", "Error fetching avatar: " + e.getMessage());
			}
		}
		
		ApplicationDialogs.showAccountDetailsDialog(this, avatarDrawable, registeredAccount, mDbAdapter.getPostsCountForAccount(registeredAccount.id));
	}
	
	private void requestTwitterAccountRegistration() {
		String authUrl = TwitterConnectionHelper.requestTwitterTokenUrl();;
		if (null != authUrl) {
			startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(authUrl)));
		}
	}
	
	@Override
	protected void onResume() {
		super.onResume();
		
		Uri uri = getIntent().getData();
		if (uri != null && uri.toString().startsWith(TwitterConnectionHelper.TWITTER_CALLBACK_URL)) {
		    String verifier = uri.getQueryParameter(OAuth.OAUTH_VERIFIER);

		    final SocialAccount newTwitterAccount = TwitterConnectionHelper.registerNewTwitterAccount(verifier);
		    if (null != newTwitterAccount) {
		    	mDbAdapter.insertAccount(newTwitterAccount);
		    	refreshAccountsList();
		    } else {
		    	ApplicationDialogs.showToast(this, "Error registering new Twitter account");
		    }
		}
	}
}
